package cn.yueranzs.system.service.impl;

import cn.hutool.captcha.CaptchaUtil;
import cn.hutool.captcha.ShearCaptcha;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONObject;
import cn.yueranzs.handler.BusinessException;
import cn.yueranzs.login.common.UserUtil;
import cn.yueranzs.response.RedisResultCode;
import cn.yueranzs.response.UserResultCode;
import cn.yueranzs.system.pojo.Menu;
import cn.yueranzs.system.pojo.Role;
import cn.yueranzs.system.service.LoginService;
import cn.yueranzs.system.service.UserAvatarService;
import cn.yueranzs.system.service.UserService;
import cn.yueranzs.utils.AliyunOSSUtil;
import cn.yueranzs.utils.MenuUtil;
import cn.yueranzs.utils.RedisUtil;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.awt.*;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;


/**
 * @author yueranzs
 * @date 2021/11/22 17:29
 */
@Service
public class LoginServiceImpl implements LoginService {

    @Resource
    private UserAvatarService userAvatarService;
    @Resource
    private UserService userService;

    /**
     * 获取验证码Base64
     *
     * @param randomCode
     * @return
     */
    @Transactional(propagation = Propagation.SUPPORTS,rollbackFor = Exception.class)
    @Override
    public String getRandomCode(String randomCode) {
        //定义图形验证码的长、宽、验证码字符数、干扰元素个数
        ShearCaptcha captcha = CaptchaUtil.createShearCaptcha(90, 34, 4, 3);
        //设置背景颜色
        captcha.setBackground(Color.WHITE);
        //验证图形验证码的有效性，返回boolean值
        captcha.verify("120");
        //将字符长存入redis，并判断redis中是否存在
        boolean redisCode = RedisUtil.set(RedisResultCode.REDIS_RANDOM_CODE.getMessage() + randomCode, captcha.getCode(), RedisResultCode.REDIS_RESULT_CODE.getCode(), TimeUnit.SECONDS);
        if (!redisCode) {
            new BusinessException(RedisResultCode.REDIS_PLEASE.getCode(), RedisResultCode.REDIS_PLEASE.getMessage());
        }
        //3.这里只返回Base64字符串用来展示
        return captcha.getImageBase64Data();
    }

    /**
     * 获取用户头像
     *
     * @param username
     * @return
     */
    @Transactional(propagation = Propagation.SUPPORTS,rollbackFor = Exception.class)
    @Override
    public String getUserAvatar(String username) {
        String userAvatar = userAvatarService.getUserAvatar(username);
        if (ObjectUtil.isNotEmpty(userAvatar)) {
            return AliyunOSSUtil.getFileUrl(userAvatar, null);
        }
        return null;
    }

    /**
     * 获取登陆人的菜单
     *
     * @return
     */
    @Transactional(propagation = Propagation.SUPPORTS,rollbackFor = Exception.class)
    @Override
    public JSONObject getUser() {
        JSONObject object = new JSONObject();
        object.set("avatarUrl",getUserAvatar(UserUtil.getUserName()));
        object.set("userName",UserUtil.getUserName());
        object.set("userId",UserUtil.getUserId());
        return object;
    }

    /**
     * 退出登录
     *
     * @return
     */
    @Transactional(propagation = Propagation.REQUIRED,rollbackFor = Exception.class)
    @Override
    public JSONObject logout() {
        JSONObject object = new JSONObject();
        if (ObjectUtil.isNotEmpty(RedisUtil.get(RedisResultCode.REDIS_TOKEN_CODE.getMessage() + UserUtil.getUserName()))) {
            //清除token
            RedisUtil.del(RedisResultCode.REDIS_TOKEN_CODE.getMessage() + UserUtil.getUserName());
            //清除认证对象，因为在springsecurity中我并没有设置session，所以不需要清空
            SecurityContextHolder.getContext().setAuthentication(null);
            object.set("code",UserResultCode.USER_LOGOUT_SUCCESS.getCode());
            object.set("message",UserResultCode.USER_LOGOUT_SUCCESS.getMessage());
            return object;
        }
        object.set("code",UserResultCode.USER_LOGOUT_ERROR.getCode());
        object.set("message",UserResultCode.USER_LOGOUT_ERROR.getMessage());
        return object;
    }

    /**
     * 获取用户菜单权限
     *
     * @return
     */
    @Override
    public List<Menu> getUserMenus() {
        return UserUtil.getUserMenu();
    }
}
